/*
 * Copyright 2009 original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and limitations under the
 * License.
 */
package cn.configleon.resource;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import cn.configleon.configurer.AbstractPropertyConfigurer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;


public class ApplicationPropertyResources extends AbstractPropertyResources {
    
    private static Logger logger = LoggerFactory.getLogger(AbstractPropertyConfigurer.class);
    
    private static final String CONFIG_PATH_VAR = "config.path";
    
    private String resourcePath;
    
    @Override
    public List<Resource> getResources(String env) throws FileNotFoundException {
        
        validateResourcePathProperty();
        List<Resource> resources = new ArrayList<Resource>();
        addResource(resources, resourcePath + "/config-default.properties");
        addResource(resources, resourcePath + "/config-web.properties");
        addResource(resources, resourcePath + "/" + resourceNamePrefix + "-" + env + ".properties");
//        addResource(resources,resourcePath + "/jdbc.properties");
        resources.addAll(super.getResources(env));
        if (resources.isEmpty()) {
            String msg = "No properties file loaded in config/resource path [" + resourcePath + "]";
            logger.error(msg);
            throw new IllegalStateException(msg);
        }
        
        return resources;
    }
    
    private void validateResourcePathProperty() {
        if (resourcePath == null) {
            resourcePath = System.getProperty(CONFIG_PATH_VAR);
        }
        
        if (StringUtils.isEmpty(resourcePath)) {
            logger.warn(
                    "The config.path is not set in JVM args. Trying to search the default project config directory");
            String defaultConfPath = detectDefaultConfigDirectory();
            if (defaultConfPath == null) {
                String msg = "The config/resource path is not determined, and needs to be set manually via variable "
                        + "[config.path].";
                logger.error(msg);
                throw new IllegalStateException(msg);
            } else {
                resourcePath = "file:" + defaultConfPath;
                logger.warn("Found the default project config directory: " + defaultConfPath);
                logger.warn("The config/resource path will be supplied instead: " + resourcePath);
            }
        } else {
            logger.info("Config/resource path: " + resourcePath);
        }
    }

    /**
     * 获取当前项目所在位置 拼接conf文件目录
     * @return conf文件目录
     */
    private String detectDefaultConfigDirectory() {
        File jarPath = new File(
                ApplicationPropertyResources.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        String appPath = jarPath.getParentFile().getAbsolutePath() + File.separator;
        logger.info("Configuration artifact classpath: " + appPath);
        int index = appPath.indexOf("WEB-INF");
        if (index <= 0) {
            return null;
        }
        appPath = appPath.substring(0, index+8);
        String[] configPaths = new String[] { appPath + "dakaqi-conf", appPath + "../conf" };
        for (String configPath : configPaths) {
            if (checkConfDirectory(configPath)) {
                return configPath;
            }
        }
        return null;
    }
    
    private boolean checkConfDirectory(String path) {
        File reportDirectory = new File(path);
        return reportDirectory.exists() && reportDirectory.isDirectory();
    }
}
